package window;

import com.alibaba.fastjson.JSONObject;
import constants.TemplateType;
import cookie.ExportTempCookie;
import cookie.ProjectCookie;
import cookie.TemplateSetting;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.DirectoryChooser;
import javafx.stage.Modality;
import javafx.stage.Screen;
import javafx.stage.Stage;
import language.Language;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import poi.ExcelHandlePipeline;
import util.ProjectUtil;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

/**
 * 用一句话描述该文件作用
 *
 * @Author pengsamkee
 * created on 2016/11/15 23:53.
 */
public class ExportWindow {

    private static final Logger logger = LoggerFactory.getLogger(ExportWindow.class);

    private final CheckBox clientCheckBox = new CheckBox(Language.getTranslation("export.client"));

    private final CheckBox serverCheckBox = new CheckBox(Language.getTranslation("export.server"));

    private final Label clientExportNameLabel = new Label(Language.getTranslation("export.client.export.type"));

    private final Label serverExportNameLabel = new Label(Language.getTranslation("export.server.export.type"));

    private final ComboBox clientExportNameComboBox = new ComboBox();

    private final ComboBox serverExportNameComboBox = new ComboBox();

    private final Label clientExportBeanDirectoryLabel = new Label(Language.getTranslation("export.client.export.bean.file.directory"));

    private final Label serverExportBeanDirectoryLabel = new Label(Language.getTranslation("export.server.export.bean.file.directory"));

    private final TextField clientExportBeanDirectoryTextField = new TextField();

    private final TextField serverExportBeanDirectoryTextField = new TextField();

    private final Button clientExportBeanDirectoryButton = new Button(Language.getTranslation("export.file.browse"), new ImageView(new Image("open_folder.png")));

    private final Button serverExportBeanDirectoryButton = new Button(Language.getTranslation("export.file.browse"), new ImageView(new Image("open_folder.png")));

    private final Label clientExportJsonDirectoryLabel = new Label(Language.getTranslation("export.client.export.json.file.directory"));

    private final Label serverExportJsonDirectoryLabel = new Label(Language.getTranslation("export.server.export.json.file.directory"));

    private final TextField clientExportBeanRootPackageTextField = new TextField();

    private final TextField serverExportBeanRootPackageTextField = new TextField();

    private final Label clientExportBeanRootPackageLabel = new Label(Language.getTranslation("export.client.export.bean.root"));

    private final Label serverExportBeanRootPackageLabel = new Label(Language.getTranslation("export.server.export.bean.root"));

    private final TextField clientExportJsonDirectoryTextField = new TextField();

    private final TextField serverExportJsonDirectoryTextField = new TextField();

    private final Button clientExportJsonDirectoryButton = new Button(Language.getTranslation("export.file.browse"), new ImageView(new Image("open_folder.png")));

    private final Button serverExportJsonDirectoryButton = new Button(Language.getTranslation("export.file.browse"), new ImageView(new Image("open_folder.png")));

    private final DirectoryChooser clientExportBeanDirectoryChooser = new DirectoryChooser();

    private final DirectoryChooser clientExportJsonDirectoryChooser = new DirectoryChooser();

    private final DirectoryChooser serverExportBeanDirectoryChooser = new DirectoryChooser();

    private final DirectoryChooser serverExportJsonDirectoryChooser = new DirectoryChooser();

    final ButtonBar exportButtonBar = new ButtonBar();

    private final Button exportButton = new Button(Language.getTranslation("export.export"));

    private ProjectCookie projectCookie;

    private static final String encoding = "UTF-8";

    public void init(Stage ownnerStage) {
        Stage stage = new Stage();
        stage.setTitle(Language.getTranslation("export.title"));
        stage.getIcons().add(new Image("app.logo.png"));
        stage.initOwner(ownnerStage);
        stage.initModality(Modality.APPLICATION_MODAL);
        stage.setWidth(800);
        stage.setHeight(500);
        stage.setMaximized(false);
        stage.setResizable(false);

        this.projectCookie = ProjectCookie.getProjectCookie();

        clientCheckBox.setSelected(true);
        clientCheckBox.selectedProperty().addListener(event -> {
            ExportTempCookie.ExportClient = clientCheckBox.isSelected();
            clientExportNameComboBox.setDisable(!clientCheckBox.isSelected());
            clientExportBeanDirectoryTextField.setDisable(!clientCheckBox.isSelected());
            clientExportBeanDirectoryButton.setDisable(!clientCheckBox.isSelected());
            clientExportJsonDirectoryTextField.setDisable(!clientCheckBox.isSelected());
            clientExportJsonDirectoryButton.setDisable(!clientCheckBox.isSelected());
            clientExportBeanRootPackageTextField.setDisable(!clientCheckBox.isSelected());
            exportButton.setDisable(!(clientCheckBox.isSelected() || serverCheckBox.isSelected()));
        });

        serverCheckBox.setSelected(true);
        serverCheckBox.selectedProperty().addListener(event -> {
            ExportTempCookie.ExportServer = serverCheckBox.isSelected();
            serverExportNameComboBox.setDisable(!serverCheckBox.isSelected());
            serverExportBeanDirectoryTextField.setDisable(!serverCheckBox.isSelected());
            serverExportBeanDirectoryButton.setDisable(!serverCheckBox.isSelected());
            serverExportJsonDirectoryTextField.setDisable(!serverCheckBox.isSelected());
            serverExportJsonDirectoryButton.setDisable(!serverCheckBox.isSelected());
            serverExportBeanRootPackageTextField.setDisable(!serverCheckBox.isSelected());
            exportButton.setDisable(!(clientCheckBox.isSelected() || serverCheckBox.isSelected()));
        });

        clientExportNameComboBox.setOnAction(event -> {
            projectCookie.setClientExportTemplateName((String) clientExportNameComboBox.getValue());
            rewriteProjectCookie();
            updateClientExportContent();
        });

        serverExportNameComboBox.setOnAction(event -> {
            projectCookie.setServerExportTemplateName((String) serverExportNameComboBox.getValue());
            rewriteProjectCookie();
            updateServerExportContent();
        });

        clientExportNameComboBox.getItems().addAll(
                this.projectCookie.getClientTypes()
        );
        clientExportNameComboBox.setValue(this.projectCookie.getClientExportTemplateName());
        clientExportNameComboBox.setPrefWidth(120);

        serverExportNameComboBox.getItems().addAll(
                this.projectCookie.getServerTypes()
        );
        serverExportNameComboBox.setValue(this.projectCookie.getServerExportTemplateName());
        serverExportNameComboBox.setPrefWidth(120);

        clientExportBeanDirectoryLabel.setMinWidth(200);
        clientExportJsonDirectoryLabel.setMinWidth(200);

        String clientExportTemplateName = projectCookie.getClientExportTemplateName();
        String serverExportTemplateName = projectCookie.getServerExportTemplateName();
        final TemplateSetting clientTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), clientExportTemplateName);
        final TemplateSetting serverTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), serverExportTemplateName);

        String clientExportBeanDirectoryPath = clientTemplateSetting.getExportBeanDirectory();
        String clientExportJsonDirectoryPath = clientTemplateSetting.getExportJsonDirectory();

        String serverExportBeanDirectoryPath = serverTemplateSetting.getExportBeanDirectory();
        String serverExportJsonDirectoryPath = serverTemplateSetting.getExportJsonDirectory();

        serverExportBeanDirectoryLabel.setMinWidth(200);
        serverExportJsonDirectoryLabel.setMinWidth(200);

        clientExportBeanDirectoryTextField.setPromptText(Language.getTranslation("export.client.export.bean.file.directory.prompt"));
        clientExportBeanDirectoryTextField.setEditable(false);
        clientExportBeanDirectoryTextField.setMinWidth(450);

        serverExportBeanDirectoryTextField.setPromptText(Language.getTranslation("export.server.export.bean.file.directory.prompt"));
        serverExportBeanDirectoryTextField.setEditable(false);
        serverExportBeanDirectoryTextField.setMinWidth(450);

        clientExportJsonDirectoryTextField.setPromptText(Language.getTranslation("export.client.export.json.file.directory.prompt"));
        clientExportJsonDirectoryTextField.setEditable(false);
        clientExportJsonDirectoryTextField.setMinWidth(450);

        serverExportJsonDirectoryTextField.setPromptText(Language.getTranslation("export.server.export.json.file.directory.prompt"));
        serverExportJsonDirectoryTextField.setEditable(false);
        serverExportJsonDirectoryTextField.setMinWidth(450);

        clientExportBeanRootPackageTextField.setPromptText(Language.getTranslation("export.client.export.bean.root.prompt"));
        clientExportBeanRootPackageTextField.setMinWidth(300);
        clientExportBeanRootPackageTextField.textProperty().addListener(event -> {
            updateTemplateSettingForClientBeanRootPackage();
        });

        serverExportBeanRootPackageTextField.setPromptText(Language.getTranslation("export.server.export.bean.root.prompt"));
        serverExportBeanRootPackageTextField.setMinWidth(300);
        serverExportBeanRootPackageTextField.textProperty().addListener(event -> {
            updateTemplateSettingForServerBeanRootPackage();
        });

        updateClientExportContent();
        updateServerExportContent();

        clientExportBeanDirectoryButton.setOnAction(event -> {
            clientExportBeanDirectoryChooser.setInitialDirectory(ProjectUtil.getExportDirectory(clientExportBeanDirectoryPath));
            clientExportBeanDirectoryChooser.setTitle("请选择客户端bean导出目录...");
            File directoryFile = clientExportBeanDirectoryChooser.showDialog(stage);
            this.updateTemplateSettingForBeanDirectory(directoryFile, clientExportBeanDirectoryTextField, clientTemplateSetting, clientExportBeanDirectoryPath);
        });

        clientExportJsonDirectoryButton.setOnAction(event -> {
            clientExportJsonDirectoryChooser.setInitialDirectory(ProjectUtil.getExportDirectory(clientExportJsonDirectoryPath));
            clientExportJsonDirectoryChooser.setTitle("请选择客户端json导出目录...");
            File directoryFile = clientExportJsonDirectoryChooser.showDialog(stage);
            this.updateTemplateSettingForJsonDirectory(directoryFile, clientExportJsonDirectoryTextField, clientTemplateSetting, clientExportJsonDirectoryPath);
        });

        serverExportBeanDirectoryButton.setOnAction(event -> {
            serverExportBeanDirectoryChooser.setInitialDirectory(ProjectUtil.getExportDirectory(serverExportBeanDirectoryPath));
            serverExportBeanDirectoryChooser.setTitle("请选择服务端bean导出目录...");
            File directoryFile = serverExportBeanDirectoryChooser.showDialog(stage);
            this.updateTemplateSettingForBeanDirectory(directoryFile, serverExportBeanDirectoryTextField, serverTemplateSetting, serverExportBeanDirectoryPath);
        });

        serverExportJsonDirectoryButton.setOnAction(event -> {
            serverExportJsonDirectoryChooser.setInitialDirectory(ProjectUtil.getExportDirectory(serverExportJsonDirectoryPath));
            serverExportJsonDirectoryChooser.setTitle("请选择服务端json导出目录...");
            File directoryFile = serverExportJsonDirectoryChooser.showDialog(stage);
            this.updateTemplateSettingForJsonDirectory(directoryFile, serverExportJsonDirectoryTextField, serverTemplateSetting, serverExportJsonDirectoryPath);
        });

        HBox clientExportNameHBox = new HBox();
        clientExportNameHBox.setPadding(new Insets(-12, 0, 0, 0));
        clientExportNameHBox.setSpacing(8);
        clientExportNameHBox.setAlignment(Pos.CENTER_LEFT);
        clientExportNameHBox.getChildren().addAll(clientExportNameLabel, clientExportNameComboBox, clientExportBeanRootPackageLabel, clientExportBeanRootPackageTextField);

        HBox serverExportNameHBox = new HBox();
        serverExportNameHBox.setPadding(new Insets(-12, 0, 0, 0));
        serverExportNameHBox.setSpacing(8);
        serverExportNameHBox.setAlignment(Pos.CENTER_LEFT);
        serverExportNameHBox.getChildren().addAll(serverExportNameLabel, serverExportNameComboBox, serverExportBeanRootPackageLabel, serverExportBeanRootPackageTextField);

        HBox clientExportBeanDiretoryHBox = new HBox();
        clientExportBeanDiretoryHBox.setPadding(new Insets(-12, 0, 0, 0));
        clientExportBeanDiretoryHBox.setSpacing(8);
        clientExportBeanDiretoryHBox.setAlignment(Pos.CENTER_LEFT);
        clientExportBeanDiretoryHBox.getChildren().addAll(clientExportBeanDirectoryLabel, clientExportBeanDirectoryTextField, clientExportBeanDirectoryButton);

        HBox serverExportBeanDiretoryHBox = new HBox();
        serverExportBeanDiretoryHBox.setPadding(new Insets(-12, 0, 0, 0));
        serverExportBeanDiretoryHBox.setSpacing(8);
        serverExportBeanDiretoryHBox.setAlignment(Pos.CENTER_LEFT);
        serverExportBeanDiretoryHBox.getChildren().addAll(serverExportBeanDirectoryLabel, serverExportBeanDirectoryTextField, serverExportBeanDirectoryButton);

        HBox clientExportJsonDiretoryHBox = new HBox();
        clientExportJsonDiretoryHBox.setPadding(new Insets(-12, 0, 0, 0));
        clientExportJsonDiretoryHBox.setSpacing(8);
        clientExportJsonDiretoryHBox.setAlignment(Pos.CENTER_LEFT);
        clientExportJsonDiretoryHBox.getChildren().addAll(clientExportJsonDirectoryLabel, clientExportJsonDirectoryTextField, clientExportJsonDirectoryButton);

        HBox serverExportJsonDiretoryHBox = new HBox();
        serverExportJsonDiretoryHBox.setPadding(new Insets(-12, 0, 0, 0));
        serverExportJsonDiretoryHBox.setSpacing(8);
        serverExportJsonDiretoryHBox.setAlignment(Pos.CENTER_LEFT);
        serverExportJsonDiretoryHBox.getChildren().addAll(serverExportJsonDirectoryLabel, serverExportJsonDirectoryTextField, serverExportJsonDirectoryButton);

        exportButton.setDefaultButton(true);
        exportButton.setOnAction(e -> {
            final String[] handleFileExtensions = {"xlsx", "xls"};
            File excelDirectory = new File(this.projectCookie.getConfigDirectoryPath());
            Queue<File> fileQueue = new ConcurrentLinkedQueue<File>();
            Collection<File> handleFiles = FileUtils.listFiles(excelDirectory, handleFileExtensions, true);
            fileQueue.addAll(handleFiles);
            System.err.println(fileQueue.size());
            ExcelHandlePipeline handlePipeline = new ExcelHandlePipeline(fileQueue, excelDirectory.getPath());
            handlePipeline.setSleepTime(200);
            new Thread(handlePipeline).start();
        });

        Button cancelButton = new Button(Language.getTranslation("export.cancel"));
        cancelButton.setOnAction(e -> stage.close());

        // Add buttons to the ButtonBar
        this.exportButtonBar.getButtons().addAll(exportButton, cancelButton);
        GridPane grid = new GridPane();
        grid.setVgap(22);
        grid.setHgap(8);
        grid.setPadding(new Insets(20, 20, 20, 20));
        grid.addRow(0, clientCheckBox);
        grid.addRow(1, clientExportNameHBox);
        grid.addRow(2, clientExportBeanDiretoryHBox);
        grid.addRow(3, clientExportJsonDiretoryHBox);
        grid.addRow(4, serverCheckBox);
        grid.addRow(5, serverExportNameHBox);
        grid.addRow(6, serverExportBeanDiretoryHBox);
        grid.addRow(7, serverExportJsonDiretoryHBox);
        grid.addRow(11, this.exportButtonBar);

        Scene scene = new Scene(new Group(), 800, 300);
        Group root = (Group) scene.getRoot();
        root.getChildren().add(grid);
        stage.setScene(scene);

        Rectangle2D primScreenBounds = Screen.getPrimary().getVisualBounds();
        stage.setX((primScreenBounds.getWidth() - stage.getWidth()) / 2);
        stage.setY((primScreenBounds.getHeight() - stage.getHeight()) / 2);

        stage.showAndWait();
    }

    private void updateClientExportContent() {
        String clientExportTemplateName = projectCookie.getClientExportTemplateName();
        final TemplateSetting clientTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), clientExportTemplateName);

        String clientExportBeanDirectoryPath = clientTemplateSetting.getExportBeanDirectory();
        String clientExportJsonDirectoryPath = clientTemplateSetting.getExportJsonDirectory();
        String clientExportBeanRootPackage = clientTemplateSetting.getExportBeanRootPackage();
        if (StringUtils.isBlank(clientExportBeanDirectoryPath)) {
            clientExportBeanDirectoryPath = System.getProperty("user.dir") + File.separator + "export" + File.separator + TemplateType.CLIENT + File.separator + clientExportTemplateName + File.separator + "bean";
            clientTemplateSetting.setExportBeanDirectory(clientExportBeanDirectoryPath);
        }
        if (StringUtils.isBlank(clientExportJsonDirectoryPath)) {
            clientExportJsonDirectoryPath = System.getProperty("user.dir") + File.separator + "export" + File.separator + TemplateType.CLIENT + File.separator + clientExportTemplateName + File.separator + "json";
            clientTemplateSetting.setExportJsonDirectory(clientExportJsonDirectoryPath);
        }
        rewriteProjectCookie();
        clientExportBeanDirectoryTextField.setText(clientExportBeanDirectoryPath);
        clientExportJsonDirectoryTextField.setText(clientExportJsonDirectoryPath);
        clientExportBeanRootPackageTextField.setText(clientExportBeanRootPackage);
    }

    private void updateServerExportContent() {
        String serverExportTemplateName = projectCookie.getServerExportTemplateName();
        final TemplateSetting serverTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), serverExportTemplateName);

        String serverExportBeanDirectoryPath = serverTemplateSetting.getExportBeanDirectory();
        String serverExportJsonDirectoryPath = serverTemplateSetting.getExportJsonDirectory();
        String serverExportBeanRootPackage = serverTemplateSetting.getExportBeanRootPackage();
        if (StringUtils.isBlank(serverExportBeanDirectoryPath)) {
            serverExportBeanDirectoryPath = System.getProperty("user.dir") + File.separator + "export" + File.separator + TemplateType.SERVER + File.separator + serverExportTemplateName + File.separator + "bean";
            serverTemplateSetting.setExportBeanDirectory(serverExportBeanDirectoryPath);
        }
        if (StringUtils.isBlank(serverExportJsonDirectoryPath)) {
            serverExportJsonDirectoryPath = System.getProperty("user.dir") + File.separator + "export" + File.separator + TemplateType.SERVER + File.separator + serverExportTemplateName + File.separator + "json";
            serverTemplateSetting.setExportJsonDirectory(serverExportJsonDirectoryPath);
        }
        rewriteProjectCookie();
        serverExportBeanDirectoryTextField.setText(serverExportBeanDirectoryPath);
        serverExportJsonDirectoryTextField.setText(serverExportJsonDirectoryPath);
        serverExportBeanRootPackageTextField.setText(serverExportBeanRootPackage);
    }

    private void updateTemplateSettingForBeanDirectory(File file, TextField textField, TemplateSetting templateSetting, String oldFilePath) {
        if (file != null) {
            String newFilePath = file.getAbsolutePath();
            textField.setText(newFilePath);
            if (!newFilePath.equals(oldFilePath)) {
                templateSetting.setExportBeanDirectory(newFilePath);
                this.rewriteProjectCookie();
            }
        }
    }

    private void updateTemplateSettingForJsonDirectory(File file, TextField textField, TemplateSetting templateSetting, String oldFilePath) {
        if (file != null) {
            String newFilePath = file.getAbsolutePath();
            textField.setText(newFilePath);
            if (!newFilePath.equals(oldFilePath)) {
                templateSetting.setExportJsonDirectory(newFilePath);
                this.rewriteProjectCookie();
            }
        }
    }

    private void updateTemplateSettingForClientBeanRootPackage() {
        String clientExportTemplateName = projectCookie.getClientExportTemplateName();
        final TemplateSetting clientTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), clientExportTemplateName);
        clientTemplateSetting.setExportBeanRootPackage(clientExportBeanRootPackageTextField.getText());
        rewriteProjectCookie();
    }

    private void updateTemplateSettingForServerBeanRootPackage() {
        String serverExportTemplateName = projectCookie.getServerExportTemplateName();
        final TemplateSetting serverTemplateSetting = ProjectCookie.getTemplateSetting(projectCookie.getTemplateSettings(), serverExportTemplateName);
        serverTemplateSetting.setExportBeanRootPackage(serverExportBeanRootPackageTextField.getText());
        rewriteProjectCookie();
    }

    private void rewriteProjectCookie() {
        try {
            FileUtils.writeStringToFile(ProjectUtil.getCookieFile("ProjectCookie.json"), JSONObject.toJSONString(this.projectCookie), encoding);
        } catch (IOException e) {
            logger.error(e.getMessage());
            e.printStackTrace();
        }
    }

}
